/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.business.fee.core.domain.action;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import info.peigen.hotpot.business.fee.core.domain.Fee;
import info.peigen.hotpot.business.fee.core.domain.FeeLog;
import info.peigen.hotpot.business.fee.core.domain.FeeRule;
import info.peigen.hotpot.business.fee.core.repository.entity.FeeLogEntity;
import info.peigen.hotpot.business.fee.core.repository.entity.FeeRuleEntity;
import info.peigen.hotpot.business.fee.facade.command.result.info.CalculateFeeResultInfo;
import info.peigen.hotpot.business.fee.facade.command.result.info.FeeInfo;
import info.peigen.hotpot.business.fee.facade.command.result.info.FeeManageInfo;
import info.peigen.hotpot.business.fee.facade.command.result.info.FeeRuleInfo;
import info.peigen.hotpot.business.fee.facade.query.result.info.QueryFeeRuleResultInfo;
import info.peigen.hotpot.common.core.result.ResultCode;
import info.peigen.hotpot.common.service.base.exception.BusinessException;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <b>(FeeConvertor)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2021/8/12
 */
public class FeeConverter {

    public static Fee convert(FeeInfo info) {
        Assert.isTrue(ObjectUtil.isNotNull(info), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeInfo]不得为Null!"));
        return BeanUtil.copyProperties(info, Fee.class);
    }

    public static CalculateFeeResultInfo convertCalculateFeeResultInfo(Fee domain) {
        Assert.isTrue(ObjectUtil.isNotNull(domain), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeInfo]不得为Null!"));
        return BeanUtil.copyProperties(domain, CalculateFeeResultInfo.class);
    }

    public static FeeInfo convert(Fee domain) {
        Assert.isTrue(ObjectUtil.isNotNull(domain), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeInfo]不得为Null!"));
        FeeInfo info = BeanUtil.copyProperties(domain, FeeInfo.class);
        info.setPayerAccountId(domain.getChargeAccount().getAccountId())
                .setPayeeAccountId(domain.getFeeAccount().getAccountId())
                .setFeeLogId(domain.getFeeLog().getFeeLogId());
        return info;
    }

    public static FeeInfo convert(FeeLogEntity entity) {
        Assert.isTrue(ObjectUtil.isNotNull(entity), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeLogEntity]不得为Null!"));
        FeeInfo info = BeanUtil.copyProperties(entity, FeeInfo.class);
        info.setPayerAccountId(entity.getAccountId());
        return info;
    }

    public static FeeManageInfo convertManageInfo(FeeLogEntity entity) {
        Assert.isTrue(ObjectUtil.isNotNull(entity), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeLogEntity]不得为Null!"));
        FeeManageInfo info = BeanUtil.copyProperties(entity, FeeManageInfo.class);
        info.setPayerAccountId(entity.getAccountId());
        return info;
    }

    public static FeeLogEntity convertFeeLog(FeeLog domain) {
        Assert.isTrue(ObjectUtil.isNotNull(domain), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeLog]不得为Null!"));
        FeeLogEntity entity = new FeeLogEntity();
        BeanUtil.copyProperties(domain, entity);
        // 把此时的收费规则转成json存储到log中
        fillLogFeeRule(domain, entity);
        return entity;
    }

    public static FeeLog convertFeeLog(FeeLogEntity entity) {
        Assert.isTrue(ObjectUtil.isNotNull(entity), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeLogEntity]不得为Null!"));
        FeeLog domain = new FeeLog();
        BeanUtil.copyProperties(entity, domain);
        return domain;
    }

    public static FeeRuleEntity convertFeeRule(FeeRule domain) {
        Assert.isTrue(ObjectUtil.isNotNull(domain), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeRule]不得为Null!"));
        FeeRuleEntity entity = new FeeRuleEntity();
        BeanUtil.copyProperties(domain, entity);
        if (ObjectUtil.isNotNull(domain.getAccount())) {
            entity.setAccountId(domain.getAccount().getAccountId());
        }
        if (ObjectUtil.isNotNull(domain.getBillingAccount())) {
            entity.setBillingAccountId(domain.getBillingAccount().getAccountId());
        }
        if (ObjectUtil.isNotNull(domain.getPayerAccount())) {
            entity.setPayerAccountId(domain.getPayerAccount().getAccountId());
        }
        if (ObjectUtil.isNotNull(domain.getPayeeAccount())) {
            entity.setPayeeAccountId(domain.getPayeeAccount().getAccountId());
        }
        return entity;
    }

    public static FeeRule convertFeeRule(FeeRuleEntity entity) {
        Assert.isTrue(ObjectUtil.isNotNull(entity), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeRuleEntity]不得为Null!"));
        FeeRule domain = new FeeRule();
        BeanUtil.copyProperties(entity, domain);
        return domain;
    }

    public static FeeRuleInfo convertFeeRuleInfo(FeeRule domain) {
        Assert.isTrue(ObjectUtil.isNotNull(domain), () -> new BusinessException(ResultCode.FAILURE, "当前对象[FeeRule]不得为Null!"));
        FeeRuleInfo feeRuleInfo = BeanUtil.copyProperties(domain, FeeRuleInfo.class);
        return feeRuleInfo;
    }

    public static void fillLogFeeRule(FeeLog feeLog, FeeLogEntity feeLogEntity) {
        FeeRule feeRule = feeLog.getRule();
        if (feeRule != null) {
            FeeLog.FeeLogRule feeLogRule = FeeLog.FeeLogRule.builder()
                    .context(feeRule.getContext())
                    .feeMethod(feeRule.getMethod())
                    .build();

            feeLogEntity.setFeeRule(JSON.toJSONString(feeLogRule));
        }
    }

    public static QueryFeeRuleResultInfo convertQueryFeeRuleInfo(FeeRuleEntity entity) {
        return BeanUtil.copyProperties(entity, QueryFeeRuleResultInfo.class);
    }

    public static List<QueryFeeRuleResultInfo> convertQueryFeeRuleInfo(List<FeeRuleEntity> entities) {
        return entities.stream().map(entity -> BeanUtil.copyProperties(entity, QueryFeeRuleResultInfo.class)).collect(Collectors.toList());
    }
}